-- Copyright (C) 1991-2011 Altera Corporation
-- Your use of Altera Corporation's design tools, logic functions 
-- and other software and tools, and its AMPP partner logic 
-- functions, and any output files from any of the foregoing 
-- (including device programming or simulation files), and any 
-- associated documentation or information are expressly subject 
-- to the terms and conditions of the Altera Program License 
-- Subscription Agreement, Altera MegaCore Function License 
-- Agreement, or other applicable license agreement, including, 
-- without limitation, that your use is for the sole purpose of 
-- programming logic devices manufactured by Altera and sold by 
-- Altera or its authorized distributors.  Please refer to the 
-- applicable agreement for further details.

-- Generated by Quartus II Version 11.0 Build 157 04/27/2011 SJ Web Edition
-- Created on Wed Sep 28 18:16:22 2011

LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY fsm_uart IS
    PORT (
        reset_i : IN  STD_LOGIC := '0';
        TxCLK_i : IN  STD_LOGIC;
        start_i : IN  STD_LOGIC := '0';
        zero_i  : IN  STD_LOGIC := '0';
        Ti_o 	: OUT STD_LOGIC;
        send_o 	: OUT STD_LOGIC;
        data_o 	: OUT STD_LOGIC;
        mode_o 	: OUT STD_LOGIC;
        shift_o	: OUT STD_LOGIC
    );
END fsm_uart;

ARCHITECTURE BEHAVIOR OF fsm_uart IS
    TYPE type_fstate IS (ST_IDLE,ST_LOAD,ST_STOP,ST_SEND);
    SIGNAL fstate 		: type_fstate;
    SIGNAL reg_fstate 	: type_fstate;
BEGIN
    PROCESS (TxCLK_i)
    BEGIN
        IF (TxCLK_i='0' AND TxCLK_i'event) THEN
            fstate <= reg_fstate;
        END IF;
    END PROCESS;

    PROCESS (fstate,reset_i,start_i,zero_i, TxCLK_i)
    BEGIN
        IF (reset_i='1') THEN
            reg_fstate <= ST_IDLE;

			Ti_o    <= '1';
			send_o  <= '1';
			data_o  <= '0';
			mode_o  <= '0';
			shift_o <= '0';

        ELSE
            Ti_o    <= '0';
            send_o  <= '0';
            data_o  <= '0';
            mode_o  <= '0';
            shift_o <= '0';

            CASE fstate IS
                WHEN ST_IDLE =>
                    IF ((start_i = '1')) THEN
                        reg_fstate <= ST_LOAD;
                    ELSIF (NOT((start_i = '1'))) THEN
                        reg_fstate <= ST_IDLE;
                    -- Inserting 'else' block to prevent latch inference
                    ELSE
                        reg_fstate <= ST_IDLE;
                    END IF;

                    Ti_o    <= '1';
                    send_o  <= '1';
                    data_o  <= '0';
                    mode_o  <= '0';
                    shift_o <= '0';

                WHEN ST_LOAD =>
                    reg_fstate <= ST_SEND;

                    Ti_o    <= '0';
                    send_o  <= '0';
                    data_o  <= '0';
                    mode_o  <= '1';
                    shift_o <= '0';

                WHEN ST_STOP =>
                    reg_fstate <= ST_IDLE  ;

                    Ti_o         <= '1';
                    send_o       <= '0';
                    data_o       <= '1';
                    mode_o       <= '0';
                    shift_o      <= TxCLK_i;

                WHEN ST_SEND =>
                    IF ((zero_i = '1')) THEN
                        reg_fstate <= ST_STOP;
                    ELSIF (NOT((zero_i = '1'))) THEN
                        reg_fstate <= ST_SEND;
                    -- Inserting 'else' block to prevent latch inference
                    ELSE
                        reg_fstate <= ST_SEND;
                    END IF;

                    Ti_o    <= '0';
                    send_o  <= '0';
                    data_o  <= '1';
                    mode_o  <= '0';
                    shift_o <= TxCLK_i;

                WHEN OTHERS => 
                    Ti_o    <= 'X';
                    send_o  <= 'X';
                    data_o  <= 'X';
                    mode_o  <= 'X';
                    shift_o <= 'X';

                    report "Reach undefined state";
            END CASE;
        END IF;
    END PROCESS;
END BEHAVIOR;
